package com.ibm.iroo.addon.activiti;

import java.util.logging.Logger;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.springframework.roo.model.JavaPackage;
import org.springframework.roo.project.ProjectOperations;
import org.springframework.roo.shell.CliAvailabilityIndicator;
import org.springframework.roo.shell.CliCommand;
import org.springframework.roo.shell.CliOption;
import org.springframework.roo.shell.CommandMarker;

/**
 * Example of a command class. The command class is registered by the Roo shell following an
 * automatic classpath scan. You can provide simple user presentation-related logic in this
 * class. You can return any objects from each method, or use the logger directly if you'd
 * like to emit messages of different severity (and therefore different colors on 
 * non-Windows systems).
 * 
 * @since 1.1.1
 */
@Component
// Use these Apache Felix annotations to register your commands class in the Roo container
@Service
public class ActivitiCommands implements CommandMarker { // All command types must implement the CommandMarker interface

	/**
	 * Get hold of a JDK Logger
	 */
	private Logger log = Logger.getLogger(getClass().getName());

	@Reference
	private ProjectOperations projectOperations;
	/**
	 * Get a reference to the ActivitiOperations from the underlying OSGi container
	 */
	@Reference
	private ActivitiOperations operations;

	/**
	 * Get a reference to the StaticFieldConverter from the underlying OSGi container;
	 * this is useful for 'type save' command tab completions in the Roo shell
	 */
	//	@Reference
	//	private StaticFieldConverter staticFieldConverter;

	/**
	 * The activate method for this OSGi component, this will be called by the OSGi container upon bundle activation 
	 * (result of the 'addon install' command) 
	 * 
	 * @param context the component context can be used to get access to the OSGi container (ie find out if certain bundles are active)
	 */
	//	protected void activate(ComponentContext context) {
	//		staticFieldConverter.add(ActivitiPropertyName.class);
	//	}

	/**
	 * The deactivate method for this OSGi component, this will be called by the OSGi container upon bundle deactivation 
	 * (result of the 'addon remove' command) 
	 * 
	 * @param context the component context can be used to get access to the OSGi container (ie find out if certain bundles are active)
	 */
	//	protected void deactivate(ComponentContext context) {
	//		staticFieldConverter.remove(ActivitiPropertyName.class);
	//	}

	/**
	 * This method is optional. It allows automatic command hiding in situations when the command should not be visible.
	 * For example the 'entity' command will not be made available before the user has defined his persistence settings 
	 * in the Roo shell or directly in the project.
	 * 
	 * You can define multiple methods annotated with {@link CliAvailabilityIndicator} if your commands have differing
	 * visibility requirements.
	 * 
	 * @return true (default) if the command should be visible at this stage, false otherwise
	 */
	@CliAvailabilityIndicator("activiti setup")
	public boolean isActivitiSetupAvailable() {
		return operations.isActivitiSetupCommandAvailable(); // This command is always available!
	}

	@CliAvailabilityIndicator("activiti explorer setup")
	public boolean isActivitiExplorerSetupAvailable() {
		//TODO { "activiti setup", "activiti binding", "activiti unbinding", "activiti sample sql/process" }
		return operations.isActivitiExplorerSetupCommandAvailable();
	}

	@CliAvailabilityIndicator("activiti samples setup")
	public boolean isActivitiSamplesSetupAvailable() {
		return operations.isActivitiSamplesSetupCommandAvailable();
	}

	/**
	 * This method registers a command with the Roo shell.
	 * 
	 * @param packageName Where to put the process definition files
	 */

	@CliCommand(value = "activiti setup", help = "Prints welcome message to the Roo shell")
	public void setupActiviti(@CliOption(key = "package", mandatory = true, help = "The package to deploy process")
	final JavaPackage packageName) {
		// *.bpmn or *.bpmn20.xml
		log.info("ActivitiCommands.setupActiviti()");
		if (!packageName.getFullyQualifiedPackageName().startsWith(
				projectOperations.getTopLevelPackage(projectOperations.getFocusedModuleName())
						.getFullyQualifiedPackageName())) {
			log.warning("Your controller was created outside of the project's top level package and is therefore not included in the preconfigured component scanning. Please adjust your component scanning manually in webmvc-config.xml");
		}
		operations.setupActiviti(packageName);
	}

	@CliCommand(value = "activiti explorer setup", help = "Prints welcome message to the Roo shell")
	public void setupActivitiExplorer() {
		// *.bpmn or *.bpmn20.xml
		log.info("ActivitiCommands.setupActiviti()");
		operations.setupActivitiExplorer();
	}

	@CliCommand(value = "activiti samples setup", help = "Copy some sample process to the project")
	public void setupActivitiSamples() {
		log.info("ActivitiCommands.setupActivitiSamples()");
		operations.setupActivitiSamples();
	}

}